﻿///////////////////////////////////////////////////////////////
// Projet serveur entreprise
// Authors: Pierre Corsini, Guillaume Blanc
// mars 2011
///////////////////////////////////////////////////////////////

using System;
using System.Collections.Generic;

using System.Text;
using System.Data.SqlClient;
using System.Data;

namespace DLL
{

    class AccessDB : IAccesBD
    {
        // La chaine de connection sql est diponible dans les "Propriétés" de la base de donnée
        private readonly String connectionString = @"Data Source=ATXPOLYTECH\SQLEXPRESS;Initial Catalog=ServerEntrepriseProjet;Integrated Security=True;Connect Timeout=30";
        private SqlConnection SqlConnect;

        public AccessDB()
        {
            this.SqlConnect = new SqlConnection(connectionString);
        }

        private SqlDataReader executeQuery(String query)
        {

            SqlCommand SqlCmd = new SqlCommand();
            SqlCmd.Connection = SqlConnect;
            SqlCmd.CommandText = query;


            if (SqlConnect.State == ConnectionState.Open)
                SqlConnect.Close();


            SqlConnect.Open();

            SqlDataReader SqlDR = SqlCmd.ExecuteReader();
            return SqlDR;
        }

        public Utilisateur extraireUtilisateur(string login, string motPasse) // OK
        {
            String query = String.Format("SELECT id,[user],pwd,nom,prenom FROM utilisateur WHERE [user] = '{0}' ", login);
            SqlDataReader sdr = this.executeQuery(query);

            Utilisateur u = null;

            if (sdr.Read())
                u = new Utilisateur(sdr.GetInt32(0), sdr.GetString(1), sdr.GetString(2), sdr.GetString(3), sdr.GetString(4));


            sdr.Close();
            return u;
        }


        public Utilisateur extraireUtilisateur(int idUtilisateur) // OK
        {
            String query = String.Format("SELECT id,[user],pwd,nom,prenom FROM utilisateur WHERE id = '{0}' ", idUtilisateur);
            SqlDataReader sdr = this.executeQuery(query);

            Utilisateur u = null;

            if (sdr.Read())
                u = new Utilisateur(sdr.GetInt32(0), sdr.GetString(1), sdr.GetString(2), sdr.GetString(3), sdr.GetString(4));


            sdr.Close();
            return u;
        }


        public bool ajouterUtilisateur(Utilisateur utilisateur) // OK
        {

            String query = String.Format("IF NOT EXISTS (SELECT * from utilisateur WHERE id='{4}') BEGIN  INSERT INTO utilisateur VALUES ({4}, '{0}', '{1}', '{2}', '{3}') END",
                utilisateur.User, utilisateur.Pwd, utilisateur.Nom, utilisateur.Prenom, utilisateur.Id);
            SqlDataReader sdr = this.executeQuery(query);

            sdr.Close();
            return sdr.RecordsAffected == 1;
        }


        public bool sauverUtilisateur(Utilisateur utilisateur) // OK
        {
            String query = String.Format("UPDATE utilisateur SET [user]='{0}', pwd='{1}', nom='{2}', prenom='{3}' WHERE id='{4}'",
                utilisateur.User, utilisateur.Pwd, utilisateur.Nom, utilisateur.Prenom, utilisateur.Id);
            SqlDataReader sdr = this.executeQuery(query);

            sdr.Close();
            return sdr.RecordsAffected == 1;
        }

        public bool ajouterConseiller(Conseiller conseiller)
        {
            if (!this.ajouterUtilisateur(conseiller))
                return false;
            return true;
            String query = String.Format("IF NOT EXISTS (SELECT * from conseiller WHERE utilisateur='{0}') BEGIN INSERT INTO conseiller values('{0}') END", conseiller.Id);
            SqlDataReader sdr = this.executeQuery(query);

            sdr.Close();
            return sdr.RecordsAffected == 1;
        }

        public bool ajouterClient(Client nouveauClient)
        {
            if (!this.ajouterUtilisateur(nouveauClient))
                return false;

            String query = String.Format("IF NOT EXISTS (SELECT * from client WHERE utilisateur='{0}') BEGIN INSERT INTO client values('{0}', null) END", nouveauClient.Id);
            SqlDataReader sdr = this.executeQuery(query);

            sdr.Close();
            return sdr.RecordsAffected == 1;
        }

        public bool ajouterCompte(Compte nouveauCompte)
        {
            String query = String.Format("IF NOT EXISTS (SELECT * from compte WHERE id='{0}') BEGIN INSERT INTO compte VALUES ('{0}', '{1}', '{2}', '{3}') END",
                nouveauCompte.Id, nouveauCompte.IdClient, nouveauCompte.Solde, nouveauCompte.Libelle);

            SqlDataReader sdr = this.executeQuery(query);

            sdr.Close();
            return sdr.RecordsAffected == 1;
        }

        public bool ajouterHistorique(Historique historique)
        {
            String query = String.Format("IF NOT EXISTS (SELECT * from historique WHERE id='{0}') BEGIN INSERT INTO historique VALUES ('{0}', '{1}', '{2}', '{3}', '{4}') END",
                 historique.Id, historique.IdCompte, historique.Somme, historique.Date, historique.Type);

            SqlDataReader sdr = this.executeQuery(query);

            sdr.Close();
            return sdr.RecordsAffected == 1; 
        }

        public List<Conseiller> extraireConseillers()
        {
            String query = "SELECT id,[user],pwd,nom,prenom FROM utilisateur, conseiller WHERE utilisateur.id = conseiller.utilisateur";
            SqlDataReader sdr = this.executeQuery(query);

            List<Conseiller> list = new List<Conseiller>();

            while (sdr.Read())
                list.Add(new Conseiller(new Utilisateur(sdr.GetInt32(0), sdr.GetString(1), sdr.GetString(2), sdr.GetString(3), sdr.GetString(4))));


            sdr.Close();
            return list;
        }

        public List<Client> extraireClients(int idConseiller)
        {
            String query = String.Format("SELECT id,[user],pwd,nom,prenom FROM utilisateur, client WHERE utilisateur.id = client.utilisateur AND client.conseiller = '{0}'", idConseiller);
            SqlDataReader sdr = this.executeQuery(query);

            List<Client> list = new List<Client>();

            while (sdr.Read())
                list.Add(new Client(new Utilisateur(sdr.GetInt32(0), sdr.GetString(1), sdr.GetString(2), sdr.GetString(3), sdr.GetString(4))));


            sdr.Close();
            return list;
        }

        public List<Compte> extraireCompte(int idClient)
        {
            String query = String.Format("SELECT id,solde,lib FROM compte WHERE compte.client = '{0}'", idClient);
            SqlDataReader sdr = this.executeQuery(query);

            List<Compte> list = new List<Compte>();
            while (sdr.Read())
            {
                list.Add(new Compte(sdr.GetInt32(0), idClient, sdr.GetSqlMoney(1).ToDouble(), sdr.GetString(2)));
            }
            
            sdr.Close();
            return list;
        }


        public List<Historique> extraireHistorique(int idCompte)
        {

            String query = String.Format("SELECT id,somme,date,type FROM historique WHERE historique.compte = '{0}'", idCompte);
            SqlDataReader sdr = this.executeQuery(query);

            List<Historique> list = new List<Historique>();
            while (sdr.Read())
                list.Add(new Historique(sdr.GetInt32(0), sdr.GetDateTime(2), sdr.GetString(3), idCompte, sdr.GetSqlMoney(1).ToInt32()));

            sdr.Close();
            return list;
        }


        public bool sauverConseiller(Conseiller conseiller)
        {
            String query = String.Format("IF NOT EXISTS (SELECT * from conseiller WHERE utilisateur='{0}') BEGIN INSERT INTO conseiller VALUES ('{0}') END",
                conseiller.Id);

            SqlDataReader sdr = this.executeQuery(query);

            sdr.Close();
            return sdr.RecordsAffected == 1; 
        }

        public bool sauverConseillers(List<Conseiller> conseillers)
        {
            foreach (Conseiller conseiller in conseillers)
                this.sauverConseiller(conseiller);

            return true;//TODO 
        }


        public bool sauverClient(Client client)
        {
            if (!this.sauverUtilisateur(client))
                return false;

            String query = String.Format("IF NOT EXISTS (SELECT * from client WHERE utilisateur='{0}') BEGIN INSERT INTO client VALUES ('{0}', '{1}') END",
                client.Id, client.IdConseiller);

            SqlDataReader sdr = this.executeQuery(query);

            sdr.Close();

            return sdr.RecordsAffected == 1; 
        }

        public bool sauverClients(List<Client> clients)
        {
            foreach (Client client in clients)
                this.sauverClient(client);

            return true;//TODO
        }

        public bool sauverCompte(Compte compte)
        {
            String query = String.Format("UPDATE compte SET client='{1}', solde='{2}', lib='{3}' WHERE id='{0}'", compte.Id, compte.IdClient, compte.Solde, compte.Libelle);
            SqlDataReader sdr = this.executeQuery(query);

            sdr.Close();
            return sdr.RecordsAffected == 1; 
        }

        public bool sauverComptes(List<Compte> comptes)
        {
            foreach (Compte compte in comptes)
                this.sauverCompte(compte);

            return true;//TODO
        }

        public bool sauverHistorique(Historique historique)
        {
            // En fait c'est ajouter plustot...
            String query = String.Format("IF NOT EXISTS (SELECT * from historique WHERE id='{0}') BEGIN INSERT INTO historique VALUES ('{0}', '{1}', '{2}', '{3}', '{4}') END",
                historique.Id, historique.IdCompte, historique.Somme, historique.Date, historique.Type);
            SqlDataReader sdr = this.executeQuery(query);

            sdr.Close();
            return sdr.RecordsAffected == 1;
        }

        public bool sauverHistoriques(List<Historique> historiques)
        {
            foreach (Historique historique in historiques)
                this.sauverHistorique(historique);

            return true;//TODO
        }

        public bool supprimerClient(int idUtilisateur)
        {
            String query = String.Format("DELETE FROM client WHERE utilisateur={0}", idUtilisateur);
            SqlDataReader sdr = this.executeQuery(query);

            sdr.Close();
            return sdr.RecordsAffected == 1;
        }

        public bool supprimerConseiller(int idUtilisateur)
        {
            String query = String.Format("DELETE FROM conseiller WHERE utilisateur={0}", idUtilisateur);
            SqlDataReader sdr = this.executeQuery(query);

            sdr.Close();
            return sdr.RecordsAffected == 1;
        }

        public bool supprimerCompte(int idCompte)
        {
            String query = String.Format("DELETE FROM compte WHERE id={0}", idCompte);
            SqlDataReader sdr = this.executeQuery(query);

            sdr.Close();
            return sdr.RecordsAffected == 1;
        }

        public bool supprimerHistorique(int idCompte)
        {
            String query = String.Format("DELETE FROM historique WHERE compte={0}", idCompte);
            SqlDataReader sdr = this.executeQuery(query);

            sdr.Close();
            return sdr.RecordsAffected == 1;
        }


        public bool affecterClient(int idClient, int idConseiller)
        {
            String query = String.Format("IF EXISTS (SELECT * from conseiller WHERE utilisateur='{1}') BEGIN UPDATE client SET conseiller='{1}' WHERE utilisateur='{0}' END", idClient, idConseiller);
            SqlDataReader sdr = this.executeQuery(query);

            sdr.Close();
            return sdr.RecordsAffected == 1; 
       
        }


        public List<Administrateur> extraireAdministrateur()
        {
            String query = String.Format("SELECT id,[user],pwd,nom,prenom FROM utilisateur, Administrateur WHERE utilisateur.id = Administrateur.utilisateur");
            SqlDataReader sdr = this.executeQuery(query);

            List<Administrateur> list = new List<Administrateur>();

            while (sdr.Read())
                list.Add(new Administrateur(new Utilisateur(sdr.GetInt32(0), sdr.GetString(1), sdr.GetString(2), sdr.GetString(3), sdr.GetString(4))));


            sdr.Close();
            return list;
        }

        public List<Client> extraireClients()
        {
            String query = String.Format("SELECT id,[user],pwd,nom,prenom FROM utilisateur, client WHERE utilisateur.id = client.utilisateur");
            SqlDataReader sdr = this.executeQuery(query);

            List<Client> list = new List<Client>();

            while (sdr.Read())
                list.Add(new Client(new Utilisateur(sdr.GetInt32(0), sdr.GetString(1), sdr.GetString(2), sdr.GetString(3), sdr.GetString(4))));


            sdr.Close();
            return list;
        }



        public Compte extraireCompteParId(int idCompte)
        {
            String query = String.Format("SELECT id,solde,lib, client FROM compte WHERE compte.id = '{0}'", idCompte);
            SqlDataReader sdr = this.executeQuery(query);


            if (sdr.Read())
                return (new Compte(sdr.GetInt32(0), sdr.GetInt32(3), sdr.GetSqlMoney(1).ToDouble(), sdr.GetString(2)));
            else
                return null;
        }

    }
}
